package com.zy.hash.consistent;
import	java.util.Random;

import cn.hutool.core.util.IdUtil;
import com.google.common.collect.Lists;

import java.util.Arrays;
import java.util.List;

/**
 * @author zhaoyi
 * @date 2021/7/21 15:11
 * 一致性性hash
 *
 * 发现一个问题 删除...
 */
public class TsHash {


    public static void main(String[] args) {
        //假设最多不超过100个缓存节点
        //初始化120个虚拟节点
        List<VirtualNode> virtualNodes = initVirtualNode(120);
        VirtualNodeManager vManager = new VirtualNodeManager();
        vManager.setVirtualNodes(virtualNodes);
        vManager.setCacheCount(0);

        //上线 缓存节点 和虚拟节点关联
        upCache(vManager);

        List<String> keys = Lists.newArrayListWithCapacity(5000);
        for (int i = 0; i < 5000; i++) {
            String s = IdUtil.fastSimpleUUID();
            vManager.put(s,i);
            keys.add(s);
        }



        //上线
        vManager.up(new CacheNode("node-new"));
        //模拟下线
        vManager.down();

        int i = 0;
        for (String key : keys) {
            //正常缓存的话 查询不到这个时间查询DB再放回缓存
            Object o = vManager.get(key);
            if (o == null){
                i++;
            }

        }
        System.out.println("缓存失效的数量"+i);





    }

    private static void upCache(VirtualNodeManager vManager) {
        vManager.up(new CacheNode("node-1"));
        vManager.up(new CacheNode("node-2"));
        vManager.up(new CacheNode("node-3"));
        vManager.up(new CacheNode("node-4"));
        vManager.up(new CacheNode("node-5"));
        vManager.up(new CacheNode("node-6"));
        vManager.up(new CacheNode("node-7"));
        vManager.up(new CacheNode("node-8"));
        vManager.up(new CacheNode("node-9"));
        vManager.up(new CacheNode("node-10"));
    }

    private static List<VirtualNode> initVirtualNode(int num) {
        int step = Integer.MAX_VALUE / (num - 1);
        System.out.println("虚拟节点 " + num + " 个,步长" + step);
        List<VirtualNode> list = Lists.newArrayList();
        Long max = (long) step;
        int id = 1;
        while (max < Integer.MAX_VALUE) {
            VirtualNode virtualNode = new VirtualNode(id++, max.intValue());
            list.add(virtualNode);
            max += step;
        }
        Long l = max - step;
        list.add(new VirtualNode(id++, Integer.MAX_VALUE));
        return list;
    }


}
